package com.example.prom.ok.y2023.work.maxmind;

import com.alibaba.fastjson.JSON;
import com.example.prom.listener.ExcelListener;
import com.example.prom.strategy.excel.CustomCellStyleStrategy;
import com.example.prom.strategy.excel.CustomColumnWidthStrategy;
import com.maxmind.geoip2.DatabaseReader;
import com.maxmind.geoip2.model.CityResponse;
import com.maxmind.geoip2.record.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
import java.util.stream.Collectors;

import static com.alibaba.excel.EasyExcelFactory.read;
import static com.alibaba.excel.EasyExcelFactory.write;

@Slf4j
public class MaxMindHandler4 {

//    public static void main(String[] args) throws Exception{
//        List<MaxMindIpReaderVO2> MaxMindIpReaderVO2S = readExcel();
//        log.info("去重前的数据总量：{}", MaxMindIpReaderVO2S.size());
//        // ip去重
//        ArrayList<MaxMindIpReaderVO2> removeDup = MaxMindIpReaderVO2S.stream().collect(Collectors.collectingAndThen(
//                Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(MaxMindIpReaderVO2::getClient_ip))), ArrayList::new));
//        log.info("去重后的数据总量：{}", removeDup.size());
//        //        System.out.println(maxMindIpReaders.size());
//        List<MaxMindIpReaderVO2> notMatchList = new ArrayList<>();
//        for (MaxMindIpReaderVO2 MaxMindIpReaderVO2 : removeDup) {
////            log.info("maxMindIpReader:{}",JSON.toJSONString(MaxMindIpReaderVO2));
//            String client_ip = MaxMindIpReaderVO2.getClient_ip();
//            MaxMindResultDTO maxMindResultDTO = validateIP(client_ip.trim());
//
//            String isoCode = maxMindResultDTO.getCountryIsoCode();
//            if (StringUtils.isEmpty(isoCode)) {
//                notMatchList.add(MaxMindIpReaderVO2);
//            }
//        }
////        writeExcel(maxMindIpReaders);
//        writeExcel(notMatchList);
//    }

    public static void main(String[] args) {
//        MaxMindResultDTO maxMindResultDTO = validateIP("1.32.239.255"); // 新加坡
//        MaxMindResultDTO maxMindResultDTO = validateIP("145.249.95.255"); // 俄罗斯联邦
        MaxMindResultDTO maxMindResultDTO = validateIP("103.25.28.255");
        System.out.println("JSON.toJSONString(maxMindResultDTO)=="+JSON.toJSONString(maxMindResultDTO));
    }

    public static List<MaxMindIpReaderVO2> readExcel() {
        String fileName = "C:\\Users\\hp\\Desktop\\ok\\data\\register_ip.xlsx";
//        String fileName = "C:\\Users\\hp\\Desktop\\ok\\work\\gatewayBannedIps.xlsx";
        ExcelListener<MaxMindIpReaderVO2> excelListener = new ExcelListener<>();
        read(fileName, MaxMindIpReaderVO2.class, excelListener).sheet().doRead();
        List<MaxMindIpReaderVO2> dataList = excelListener.getDataList();
        return dataList;
    }

    public static void writeExcel(List<MaxMindIpReaderVO2> writerList){
        String writeFileName = "C:\\Users\\hp\\Desktop\\ok\\data\\register_ip001.xlsx";
        write(writeFileName, MaxMindIpReaderVO2.class).sheet().head(MaxMindIpReaderVO2.class)
                .registerWriteHandler(new CustomColumnWidthStrategy())
                .registerWriteHandler(new CustomCellStyleStrategy()).doWrite(writerList);
    }

    public static MaxMindResultDTO validateIP(String ip) {
        MaxMindResultDTO resultDTO = new MaxMindResultDTO();
        try {
            // A File object pointing to your GeoIP2 or GeoLite2 database
            File database = new File("C:\\Users\\hp\\Desktop\\ok\\work\\GeoIP2-City_20230801\\GeoIP2-City.mmdb");

// This creates the DatabaseReader object. To improve performance, reuse
// the object across lookups. The object is thread-safe.
            DatabaseReader reader = new DatabaseReader.Builder(database).build();

            InetAddress ipAddress = InetAddress.getByName(ip);

// Replace "city" with the appropriate method for your database, e.g.,
// "country".
            CityResponse response = reader.city(ipAddress);

            Country country = response.getCountry();
            System.out.println("country:"+country);
//        System.out.println(country.getIsoCode());            // 'US'
//        System.out.println(country.getName());               // 'United States'
//        System.out.println(country.getNames().get("zh-CN")); // '美国'

            Subdivision subdivision = response.getMostSpecificSubdivision();
            System.out.println("subdivision:"+subdivision);
//        System.out.println(subdivision.getName());    // 'Minnesota'
//        System.out.println(subdivision.getNames().get("zh-CN"));    // 'Minnesota'
//        System.out.println(subdivision.getIsoCode()); // 'MN'

            City city = response.getCity();
            System.out.println("city:"+city);
//        System.out.println(city.getName()); // 'Minneapolis'
//        System.out.println(city.getNames().get("zh-CN")); // 'Minneapolis'

            Postal postal = response.getPostal();
            System.out.println("postal:"+postal);
//        System.out.println(postal.getCode()); // '55455'

            Location location = response.getLocation();
            System.out.println("location:"+location);
//        System.out.println(location.getLatitude());  // 44.9733
//        System.out.println(location.getLongitude()); // -93.2323


            resultDTO.setCountryIsoCode(country.getIsoCode());
            resultDTO.setCountryNameEn(country.getName());
            resultDTO.setCountryNameZh(country.getNames().get("zh-CN"));
            String ruCountry = country.getNames().get("ru-RU");
            log.info("ruCountry:{}",ruCountry);
            resultDTO.setRegionIsoCode(subdivision.getIsoCode());
            resultDTO.setRegionNameEn(subdivision.getName());
            resultDTO.setRegionNameZh(subdivision.getNames().get("zh-CN"));
            resultDTO.setCityNameEn(city.getName());
            resultDTO.setCityNameZh(city.getNames().get("zh-CN"));
            resultDTO.setLatitude(location.getLatitude());
            resultDTO.setLongitude(location.getLongitude());
            if (StringUtils.isEmpty(country.getIsoCode())){
                Country registeredCountry = response.getRegisteredCountry();
                resultDTO.setCountryIsoCode(registeredCountry.getIsoCode());
                resultDTO.setCountryNameEn(registeredCountry.getName());
                resultDTO.setCountryNameZh(registeredCountry.getNames().get("zh-CN"));
            }

            System.out.println("JSON.toJSONString(registeredCountry)--"+JSON.toJSONString(response.getRegisteredCountry()));

        } catch (Exception e){
            log.error("ip解析异常,ip:{}", ip, e);
            resultDTO.setRegionNameEn(e.getMessage());
            resultDTO.setRegionNameZh(e.getMessage());
        }
        return resultDTO;
    }
}
